package com.ge.med.cchelper.listener;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.commands.Category;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IExecutionListener;
import org.eclipse.core.commands.NotHandledException;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;

import com.ge.med.cchelper.Constants;
import com.ge.med.cchelper.bean.CSession;
import com.ge.med.cchelper.popup.job.UploadVobFileJob;
import com.ge.med.cchelper.util.LogUtil;
import com.ge.med.cchelper.util.PropHelper;
import com.ge.med.cchelper.util.ReourceHelper;
import com.ge.med.cchelper.util.TextHelper;

public class SaveListener implements IExecutionListener {
	private static final String CMD_SAVE_ID = "org.eclipse.ui.file.save";
	private static final String CMD_SAVE_ALL_ID = "org.eclipse.ui.file.saveAll";
	//private IResource[] resource;
	List<IResource> resources = new ArrayList<IResource>();
	private String cmdName;
	private String cmdDesc;
	private Category saveCategory;

	public void notHandled(String arg0, NotHandledException arg1) {

	}

	public void postExecuteFailure(String arg0, ExecutionException arg1) {

	}

	public void postExecuteSuccess(String arg0, Object arg1) {
		// System.out.println("::::::::::::::::::::postExecuteSuccess");
			if (isInSaveCommand(arg0) || isInSaveAllCommand(arg0)) {
				//System.out.println("::::::::::::::::::::save Success cmd:"+arg0+",resources:"+resources.size());
				if (!resources.isEmpty()) {
					ReourceHelper resource = ReourceHelper.getResource();
					if(resource==null){
						MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Warning",
								"System can not synchronize with clearcase server.\r\nPlease login server and save this file again.");
						return;
					}else{
						IProject project = ReourceHelper.getProject();
						if(project==null){
							MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Warning",
									"System can not synchronize with clearcase server.\r\nPlease login server and save this file again.");
							return;
						}
						CSession session = resource.getSession(project.getName());

						if (session==null||session.getHost() == null) {
							MessageDialog.openWarning(Display.getCurrent().getActiveShell(), "Warning",
									"System can not synchronize with clearcase server.\r\nPlease login server and save this file again.");
							return;
						}
					}
					
					UploadVobFileJob job = new UploadVobFileJob("synchronize file...", resources);
					job.schedule();
				}
			}
	}

	public void preExecute(String arg0, ExecutionEvent arg1) {
		resources.clear();
		if (CMD_SAVE_ID.equals(arg0) || CMD_SAVE_ALL_ID.equals(arg0)) {

			// System.out.println(":::::::::::::::command cmd:"+arg0);
			Command com = arg1.getCommand();
			if (!com.isDefined()) {
				com.define(cmdName, cmdDesc, saveCategory);
			}

			boolean hasNocheck = false;
			
			if (isInSaveCommand(arg0)) {
				hasNocheck = hasNoCheckoutFileForSingleDirty(arg1);
			}else if (isInSaveAllCommand(arg0)){
				hasNocheck = hasNoCheckoutFileForMultiDirty(arg1);
			}
			
			if (hasNocheck) {
				try {
					cmdName = com.getName();
					cmdDesc = com.getDescription();
					saveCategory = com.getCategory();
					com.undefine();
					
					MessageDialog.openError(Display.getDefault()
							.getActiveShell(), "Error",
							"Please check out file!");
				} catch (NotDefinedException e) {
					e.printStackTrace();
					LogUtil.err(e.getMessage());
				}
			}
		}

	}


	public boolean hasNoCheckoutFileForSingleDirty(ExecutionEvent event) {
		IEditorPart dirtyEditor = HandlerUtil.getActiveEditor(event);
		IResource resource = getActiveFile(dirtyEditor);
		boolean hasNocheckout = isNoCheckoutFordirtyEdit(resource);
		return !hasNocheckout;
	}
	
	public boolean hasNoCheckoutFileForMultiDirty(ExecutionEvent event) {
		IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
		if (window == null) {
			// action has been disposed
			return false;
		}
		IWorkbenchPage page = window.getActivePage();
		final IEditorPart[] dirtyEditors = page.getDirtyEditors();

		final int editorsCount = dirtyEditors.length;
		if (editorsCount == 0) {
			return false;
		}
		
		for (int i = 0; i < editorsCount; i++) {
			IEditorPart part = dirtyEditors[i];
			//System.out.println(":::::::::try to save part:" + part.getTitle());
			IResource resource = getActiveFile(part);
			boolean hasNocheckout = isNoCheckoutFordirtyEdit(resource);
			if (!hasNocheckout)
				return true;
		}

		return false;
		// IRunnableWithProgress runnable = new IRunnableWithProgress() {
		//
		// public void run(IProgressMonitor monitor)
		// throws InvocationTargetException, InterruptedException {
		// monitor.beginTask("Converting tabs <-> spaces before save",
		// editorsCount);
		// try {
		// for (int i = 0; i < editorsCount; i++) {
		// if (monitor.isCanceled()) {
		// break;
		// }
		// monitor.worked(1);
		// IEditorPart part = dirtyEditors[i];
		// spacesAction.setActiveEditor(null, part);
		// boolean trim = spacesAction.isSaveAndTrimEnabled();
		// boolean convert = spacesAction
		// .isSaveAndConvertEnabled();
		// if (trim || convert) {
		// if (EclipseUtils.matchFilter(part,
		// spacesAction.getCombinedPreferences())) {
		// continue;
		// }
		// monitor.subTask(part.getTitle());
		// final IAction action;
		// if (spacesAction.isDefaultTabToSpaces()) {
		// action = tabsToSpaces;
		// } else {
		// action = spacesToTabs;
		// }
		// spacesAction.run(action);
		// }
		// }
		// } finally {
		// monitor.done();
		// }
		// }
		// };

		// try {
		// PlatformUI.getWorkbench().getProgressService()
		// .run(false, true, runnable);
		// } catch (InvocationTargetException e) {
		// AnyEditToolsPlugin.logError("Error during custom pre-save action",
		// e);
		// } catch (InterruptedException e) {
		// // user cancel
		// }
	}

	public static boolean isValidSelection(ISelection selection) {
		return (selection != null) && (!selection.isEmpty());
	}

	private boolean isInSaveCommand(final String commandId) {
		return CMD_SAVE_ID.equals(commandId);
	}

	private boolean isInSaveAllCommand(final String commandId) {
		return CMD_SAVE_ALL_ID.equals(commandId);
	}
	

	private boolean isNoCheckoutFordirtyEdit(IResource resource) {
		if (resource != null) {
			String allPath = resource.getFullPath().toString();
			//System.out.println(":::::::::file path:" + allPath);
			IProject project = resource.getProject();
			String confdir = project.getLocation().toOSString();

			String checkConf = confdir + File.separator
					+ TextHelper.CHECKOUT_FILE;
			String cchelperConfig = confdir + File.separator+PropHelper.CONFIG_FILE;
			File cchelperFile = new File(cchelperConfig);
			if (cchelperFile.exists()) {
				String filePath = resource.getParent().getFullPath()
						.toOSString();
				String vobPath = project.getProject().getFullPath()
						.toOSString()
						+ File.separator + Constants.VOB;
				if (filePath.startsWith(vobPath)) {
					try {
						if (TextHelper.isExists(checkConf, allPath)) {
							resources.add(resource);
						} else {
							return false;
						}
					} catch (Exception e) {
						e.printStackTrace();
						LogUtil.err(e.getMessage());
					}
				}
			}

		}
		return true;
	}

	private IResource getActiveFile(IEditorPart actEditor) {
		IEditorInput input = actEditor.getEditorInput();
		Object adaptable = input.getAdapter(IFile.class);
		IResource resource = null;
		if ((adaptable instanceof IResource)) {
			resource = (IResource) adaptable;
		}
		return resource;
	}

}
